import React from 'react'
import IScroll from './iscroll-probe'
import { View, Image, Text } from '@tarojs/components'
import { isPassive } from './demoUtils'
import './index.scss'

export enum RefreshState {
    Idle = 'Idle',
    HeaderRefreshing = 'HeaderRefreshing',
    FooterRefreshing = 'FooterRefreshing',
    NoMoreData = 'NoMoreData',
    Failure = 'Failure',
    EmptyData = 'EmptyData',
    None = 'None',
}



type Prop = {

    options?: any;
    children: React.ReactNode;
    /**控制刷新状态，默认没有 */
    refreshState?: RefreshState;
    style?: React.CSSProperties;
    containerStyle?: React.CSSProperties;
    /**上啦刷新 */
    onHeaderRefresh?: () => void;
    /**下拉加载 */
    onFooterRefresh?: () => void;
    onEmptyRefresh?: () => React.ReactNode;
}


type StateProp = {
    refreshState?: RefreshState;
}
type StyleProp = {
    headerStyle?: React.CSSProperties;
    footerStyle?: React.CSSProperties;
}

type StateReducerProp = (state: StateProp, action: Partial<StateProp>) => StateProp
type StyleReducerProp = (state: StyleProp, action: Partial<StyleProp>) => StyleProp
const reduer = (state, action) => ({ ...state, ...action })

export default React.forwardRef((props: Prop, ref) => {

    const {
        options,
        style,
        containerStyle,
        refreshState,
        onHeaderRefresh,
        onFooterRefresh
    } = props
    const [state, dispatch] = React.useReducer<StateReducerProp>(
        reduer,
        {
            refreshState: RefreshState.None
        })

    const [styleState, styleDispatch] = React.useReducer<StyleReducerProp>(
        reduer,
        {
            headerStyle: styles.header,
            footerStyle: styles.footer
        })



    React.useImperativeHandle(ref, () => ({
        showHeaderRefresh: () => {
            scrollToTop()
        },
        showFooterRefresh: () => {
            scrollToBottom()
        },
        showFooterMode: (mode: RefreshState.NoMoreData | RefreshState.Failure | RefreshState.EmptyData | RefreshState.None) => {
            dispatch({refreshState:mode})
            setTimeout(() => {
                _myScrollRef.current?.refresh()
            }, 10)
        }
    }), [])


    React.useEffect(() => {
        console.log('useEffect init')
        loaded()
        return () => {
            console.log('useEffect release')
            _myScrollRef.current?.destroy()
            _myScrollRef.current = undefined
        }
    }, [])
    React.useEffect(() => {
        let rect = wrapperRef.current?.getBoundingClientRect()
        containerRef.current.style.minHeight = `${rect.height + 1}px`
        _myScrollRef.current?.refresh()
    }, [props.children, state.refreshState])


    const _myScrollRef = React.useRef<IScroll>()



    const refreshStateRef = React.useRef<RefreshState>()






    const loaded = () => {

        let myScroll = new IScroll('#wrapper', Object.assign({}, _options, options));
        _myScrollRef.current = myScroll
        myScroll.on('scroll', () => {
            // console.log('scroll', myScroll.y, refreshStateRef.current)
            if (myScroll.y > 44 && refreshStateRef.current != RefreshState.HeaderRefreshing && touchmoveRef.current) {
                // dispatch({ refreshState: RefreshState.HeaderRefreshing })
                refreshStateRef.current = RefreshState.HeaderRefreshing
                onHeaderRefresh && onHeaderRefresh()

                // myScroll.scrollTo(0, -100, 150)
                // myScroll.refresh()
            }
            let y = myScroll.y
            let offset = y - 44
            let scrollerHeight = myScroll.scrollerHeight
            let wrapperHeight = myScroll.wrapperHeight
            if (offset < wrapperHeight - scrollerHeight && refreshStateRef.current != RefreshState.FooterRefreshing && touchmoveRef.current) {
                refreshStateRef.current = RefreshState.FooterRefreshing
                onFooterRefresh && onFooterRefresh()
            }
        })


        myScroll.on('scrollEnd', () => {
            console.log('scrollEnd touchmoveRef', myScroll.y, state.refreshState)
            let y = myScroll.y
            let scrollerHeight = myScroll.scrollerHeight
            let wrapperHeight = myScroll.wrapperHeight

            if (y == 0 && refreshStateRef.current == RefreshState.HeaderRefreshing) {
                scrollToTop()
            }

            if (y == wrapperHeight - scrollerHeight && refreshStateRef.current == RefreshState.FooterRefreshing) {
                scrollToBottom()
            }


            console.log({
                y,
                scrollerHeight,
                wrapperHeight
            })

        })


    }


    const scrollToTop = () => {
        dispatch({ refreshState: RefreshState.HeaderRefreshing })
        setTimeout(() => {
            _myScrollRef.current?.refresh()
        }, 10)
    }

    const scrollToBottom = () => {
        let scrollerHeight = _myScrollRef.current?.scrollerHeight
        let wrapperHeight = _myScrollRef.current?.wrapperHeight
        dispatch({ refreshState: RefreshState.FooterRefreshing })
        setTimeout(() => {
            _myScrollRef.current?.refresh()
            setTimeout(() => {
                _myScrollRef.current?.scrollTo(0, wrapperHeight - scrollerHeight)
            })
        }, 10)
    }


    const onTouchStart = () => {
        touchmoveRef.current = true
    }
    const onTouchEnd = () => {
        touchmoveRef.current = false
    }

    const touchmoveRef = React.useRef<boolean>(false)
    const headerRef = React.useRef<any>()
    const footerRef = React.useRef<any>()
    const containerRef = React.useRef<any>()
    const wrapperRef = React.useRef<any>()
    return (
        <View id='wrapper' ref={wrapperRef} style={Object.assign({}, styles.wrapper, style)}
            onTouchStart={onTouchStart}
            onTouchEnd={onTouchEnd}
        >

            <View id="scroller" style={Object.assign({}, styles.scroller, containerStyle)}>
                <View id='header' ref={headerRef} style={styleState.headerStyle}>
                    <Text >下拉刷新</Text>
                </View>

                <View ref={containerRef} style={styles.containerStyle}>
                    {props.children}
                    {(state.refreshState == RefreshState.FooterRefreshing || state.refreshState == RefreshState.HeaderRefreshing) &&
                        <View style={{ display: 'flex', width: '100%', height: '44px', justifyContent: 'center', alignItems: 'center', backgroundColor: 'white' }}>
                            <Image src={require('./loading.png')} style={styles.loading} mode='aspectFit' />
                        </View>
                    }
                    {state.refreshState == RefreshState.NoMoreData &&
                        <View style={{ display: 'flex', width: '100%', height: '44px', justifyContent: 'center', alignItems: 'center', backgroundColor: 'white' }}>
                            <Text>已经全部加载完毕</Text>
                        </View>
                    }
                    {state.refreshState == RefreshState.Failure &&
                        <View style={{ display: 'flex', width: '100%', height: '44px', justifyContent: 'center', alignItems: 'center', backgroundColor: 'white' }}>
                            <Text>服务器正在出小差，请稍后重试～</Text>
                        </View>
                    }
                    {state.refreshState == RefreshState.EmptyData &&
                        <View style={{ display: 'flex', width: '100%', height: '44px', justifyContent: 'center', alignItems: 'center', backgroundColor: 'white' }}>
                            <Text>暂无数据～</Text>
                        </View>
                    }
                </View>
                <View id='footer' ref={footerRef} style={styleState.footerStyle}>
                    <Text >上拉刷新</Text>
                </View>
            </View>


        </View>
    )
})



const styles: Record<string, React.CSSProperties> = {

    wrapper: {
        display: 'flex',
        flexDirection: 'column',
        flexGrow: 1,
        backgroundColor: 'cyan',
        overflow: 'hidden'
    },
    scroller: {
        // position: 'absolute',
        // height: '100%',
        // width: '100%',
        display: 'flex',
        flexDirection: 'column',
        flexGrow: 1,
        WebkitTapHighlightColor: 'turquoise',
        WebkitTransform: 'translateZ(0)',/* Safari 和 Chrome */
        transform: 'translateZ(0)',
        WebkitUserSelect: 'none',/* Safari */
        userSelect: 'none',/* Standard syntax */
        textSizeAdjust: 'none',
    },
    containerStyle: {
        display: 'flex',
        flexDirection: 'column',
        // flexGrow: 1,
        // height: '1000px',
        backgroundColor: 'yellow'
    },

    header: {
        position: 'absolute',
        zIndex: 1,
        top: '-44px', left: 0,
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        width: '100%',
        height: '44px',
        backgroundColor: 'red',
    },
    footer: {
        position: 'absolute',
        zIndex: 1,
        bottom: '-44px', left: 0,
        display: 'flex',
        width: '100%',
        height: '44px',
        backgroundColor: 'blue',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
    },
    loading: {
        animation: 'animation_rotate_360 infinite 1s linear',
        width: '24px',
        height: '24px',
    }
}






const _options = {
    //默认情况下，仅启用垂直滚动。如果您需要水平滚动，则必须设置scrollX为true
    //默认值：scrollX: false,scrollY: true
    // scrollX: false, 
    // scrollY: true, 
    //有时您想保留原生垂直滚动但能够添加水平 iScroll（可能是轮播）。将此设置为true，iScroll 区域将仅对水平滑动做出反应。垂直滑动自然会滚动整个页面。
    // eventPassthrough:false,
    // 默认iscroll会拦截元素的默认事件处理函数，我们需要响应onClick，因此要配置
    preventDefault: false,
    // 禁止缩放
    zoom: false,
    // 支持鼠标事件，因为我开发是PC鼠标模拟的
    mouseWheel: true,
    // 滚动事件的探测灵敏度，1-3，越高越灵敏，兼容性越好，性能越差
    probeType: 3,
    // 拖拽超过上下界后出现弹射动画效果，用于实现下拉/上拉刷新
    bounce: true,
    // 展示滚动条
    // scrollbars: true,
    // interactiveScrollbars:true,
    //抖动
    // bounceEasing: 'elastic',
    // bounceTime: 1200,

    useTransition: true
}